/**
 * Universidad del Valle de Guatemala
 * Algoritmos y estructura de Datos.
 * @autor Evelyn Lissete Paiz   11365
 * Sección: 20
 * 15 de julio, 2012
 * Programa que permite implementar de una calculadora en forma postfix.
 */

package hoja_dos;

import java.util.EmptyStackException;

public class Calculadora {

    //------------------------------------------------------------------------
    // Atributos:
    //------------------------------------------------------------------------
    
    //Pila para guardar operandos.
    private Stack <Integer> pila;
    
    //------------------------------------------------------------------------
    // Constructor:
    //------------------------------------------------------------------------

    /**
     * Método que permite la creación de una nueva calculadora.
     * pre: -
     * post: Se construye una nueva calculadora.
     */
    public Calculadora() {
        this.pila = new StackVector <Integer>();
    }
    
    /**
     * Método que permite realizar los calculos.
     * pre: Se debe de haber ingresado los valores en forma postfix.
     * post: Se realiza el cálculo y se obtiene el resultado.
     * @param cadena La cadena que contiene todas las operaciones.
     * @return El resultado de la operación.
     */
    
    public int calcular (String cadena){
        //Se comprueba que se haya ingresado por lo menos 2 operandos y 1 operación.
        if (cadena.length()<4){
            throw new EmptyStackException();
        }
        else{
            //Encargado de llevar conteo del ciclo
            int cont=cadena.length();
            //Encargado de guardar el segundo operando momentaneamente.
            int operando2;
            //Encargados de llevar control de la cadena
            int uno = 0;
            int dos = 0;
            //Se inicia el ciclo:
            while (cont>0){
                //Se verifica si en la cadena es está viendo el final de un número u
                //operación.
                if (String.valueOf(cadena.charAt(uno)).equalsIgnoreCase(" ")){
                    try{
                        //Trata de guardar el número en la pila.
                        pila.push(Integer.valueOf(cadena.substring(dos, uno)));
                        dos=uno+1;     
                    }
                    //Si no es un número, entonces es un operador.
                    catch(Exception ex){
                        //Verifica si es una suma.
                        if (String.valueOf(cadena.charAt(uno-1)).equalsIgnoreCase("+")){
                            //Realiza la operación y luego guarda el resultado en la pila.
                            pila.push(pila.pop()+pila.pop());
                        }
                        //Verifica si es una multiplicación.
                        if (String.valueOf(cadena.charAt(uno-1)).equalsIgnoreCase("*")){
                            //Realiza la operación y luego guarda el resultado en la pila.
                            pila.push(pila.pop()* pila.pop());
                        }
                        //Verifica si es una división.
                        if (String.valueOf(cadena.charAt(uno-1)).equalsIgnoreCase("/")){
                            //Realiza la operación y luego guarda el resultado en la pila.
                            operando2=pila.pop();
                            pila.push(pila.pop()/operando2);
                        }
                        //Verifica si es una resta
                        if (String.valueOf(cadena.charAt(uno-1)).equalsIgnoreCase("-")){
                            //Realiza la operación y luego guarda el resultado en la pila.
                            operando2=pila.pop();
                            pila.push(pila.pop()-operando2);
                        }
                        //Mueve de lugar el apuntador de la cadena.
                        dos=uno+1;
                    }
                }
                //Decrementa el contador.
                cont--;
                //Mueve de lugar el apuntador de la cadena.
                uno++;
            }
            //Regresa el valor de toda la operación.
            if (pila.size()==1){
                return pila.pop();
            }
            else{
                //Se limpia la pila.
                while (pila.empty()==false){
                    pila.pop();
                }
                throw new EmptyStackException();
            }
        }
    }    
}
